#include <stdio.h>
#include "ds18b20.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

TaskFunction_t ds18b20_handle = NULL;

float ds18b20_get_temperature(void);

    float T = 0;
void ds18b20_task(void *Pvparam)
{
    while(1)
    {
        
            T = ds18b20_get_temperature();
            // printf("T:%.1f \r\n", T);
            vTaskDelay(pdMS_TO_TICKS(500));
    }
}

void ds18b20_init(void)
{
    gpio_reset_pin(DS18B20_GPIO);

    gpio_set_direction(DS18B20_GPIO, GPIO_MODE_INPUT_OUTPUT_OD);
    xTaskCreate(ds18b20_task, "ds18b20_task", 4096, NULL, 1, &ds18b20_handle);
}

void ds18b20_reset(void)
{
    gpio_set_level(DS18B20_GPIO, 0);
    ets_delay_us(750); 
    gpio_set_level(DS18B20_GPIO, 1);
    ets_delay_us(15); 
}

uint8_t ds18b20_check(void) /* return 0:succeed   1:fail */
{
    uint8_t retry = 0, rval = 0; 

    while (gpio_get_level(DS18B20_GPIO) && retry < 200)
    {
        retry++;
        ets_delay_us(1);
    } 

    if (retry >= 200) /* ³¬Ê± */
    {
        rval = 1;
    }
    else
    {
        retry = 0;

        while (!gpio_get_level(DS18B20_GPIO) && retry < 240)
        {
            retry++;
            ets_delay_us(1);
        }

        if (retry >= 240)
        {
            rval = 1;
        }
    }

    return rval;
}

void ds18b20_write_0(void)
{
    gpio_set_level(DS18B20_GPIO, 0);
    ets_delay_us(60);  
    gpio_set_level(DS18B20_GPIO, 1);
    ets_delay_us(2);   
}

void ds18b20_write_1(void)
{
    gpio_set_level(DS18B20_GPIO, 0);
    ets_delay_us(2);   
    gpio_set_level(DS18B20_GPIO, 1);
    ets_delay_us(60);  
}

void ds18b20_write_byte(uint8_t data)
{
    uint8_t j;

    for (j = 0; j < 8; j++)
    {
        if (data & 0x01)
        {
            ds18b20_write_1(); /* Write 1*/
        }
        else
        {
            ds18b20_write_0(); /* Write 0*/
        }

        data >>= 1; /* ÓÒÒÆ£¬»ñÈ¡¸ßÒ»Î»Êý¾Ý */
    }
}

uint8_t ds18b20_read_bit(void)
{
    uint8_t data = 0;

    gpio_set_level(DS18B20_GPIO, 0);
    ets_delay_us(2);       /* ÑÓÊ±2us */
    gpio_set_level(DS18B20_GPIO, 1);
    ets_delay_us(12);      /* ÑÓÊ±12us */

    if (gpio_get_level(DS18B20_GPIO))
    {
        data = 1;
    }

    ets_delay_us(50);
    return data;
}

uint8_t ds18b20_read_byte(void)
{
    uint8_t i, b, data = 0;

    for (i = 0; i < 8; i++)
    {

        b = ds18b20_read_bit();
        
        data |= b << i;
    }

    return data;
}

float ds18b20_get_temperature(void)
{
    uint8_t TL, TH;
    uint16_t temp = 0;
    float temperature = 0;

    ds18b20_reset();
    ds18b20_check();

    ds18b20_write_byte(0xCC);

    ds18b20_write_byte(0x44);

    ds18b20_reset();
    ds18b20_check();

    ds18b20_write_byte(0xCC);

    ds18b20_write_byte(0xBE);

    TL = ds18b20_read_byte();
    TH = ds18b20_read_byte();


    temp = TL + (TH << 8);
    temperature = temp*0.0625f;
    return temperature;
}



